home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / 7up_pd / undo.c < prev    next >
C/C++ Source or Header  |  1998-10-29  |  6KB  |  274 lines

  1. /* simple UNDO/REDO Funktion */
  2. /*****************************************************************************
  3. *
  4. *                                              7UP
  5. *                                         Modul: UNDO.C
  6. *                                     (c) by TheoSoft '92
  7. *
  8. *****************************************************************************/
  9. #include <portab.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <aes.h>
  14.  
  15. #include "alert.h"
  16.  
  17. #include "7up.h"
  18. #include "windows.h"
  19.  
  20. #define LINEUNDO  (-1)
  21. #define LINEPAST  (-2)
  22. #define CUTLINE    (-3)
  23. #define CUTPAST    (-4)
  24. #define PASTCUT    (-5)
  25. #define BACKSPACE (0x0008)
  26. #define RETURN     (0x000D)
  27.  
  28. /*
  29. extern long lasthfirst,begline,endline;
  30. */
  31. typedef struct
  32. {
  33.     int menu,item;
  34.     LINESTRUCT *blkbeg, *blkend;  /* Für PASTE */
  35.     long wline, begline, endline; /* Für CUT    */
  36.     int begcol, endcol;
  37.     int blktype;                        /* Blocktyp */
  38.     char string[STRING_LENGTH+2]; /* Lineundo */
  39.     char *cp;
  40.     int row,col;
  41.     int flag;                            /* 0 oder -1 : Fehler */
  42. } UNDO;
  43.  
  44. UNDO undo={FALSE,FALSE,NULL,NULL,0L,0L,0L,0,0,0,"",NULL,-1,-1,TRUE};
  45.  
  46. int Wrestblk(WINDOW *wp, UNDO *undo, LINESTRUCT **beg, LINESTRUCT **end);
  47.  
  48. void free_undoblk(WINDOW *wp, LINESTRUCT *line)
  49. {
  50.     if(!wp)
  51.         return;
  52.     if(line)
  53.     {
  54.         do
  55.         {
  56.             if(line->string)
  57.                 free(line->string);
  58.             if(line->prev)
  59.                 free(line->prev);
  60.             if(line->next)
  61.                 line=line->next;
  62.             else
  63.             {
  64.                 free(line);
  65.                 line=NULL;
  66.             }
  67.         }
  68.         while(line);
  69.         undo.blkbeg=undo.blkend=NULL;
  70.     }
  71. }
  72.  
  73. static char savestr[STRING_LENGTH+2];
  74.  
  75. void store_undo(WINDOW *wp, UNDO *undo, LINESTRUCT *beg, LINESTRUCT *end, int menu, int item)
  76. {                                                /* Ausschneideinformationen sichern */
  77.     long lines, chars;
  78.     if(wp)
  79.     {
  80.         Wblksize(wp,beg,end,&lines,&chars);
  81.         undo->menu=menu;
  82.         undo->item=item;
  83.         undo->wline=wp->hfirst/wp->hscroll;
  84.         undo->begline=wp->row+wp->hfirst/wp->hscroll;
  85.         undo->begcol=wp->col+wp->wfirst/wp->wscroll;
  86.         undo->endline=undo->begline+lines;
  87.         undo->endcol=end->used;
  88.  
  89.         if(end->used==0)
  90.         {  /* eine ganze Zeile mit Zeilenumbruch z.B. ^Y */
  91.             undo->endline--;
  92.             undo->endcol=STRING_LENGTH;
  93.         }
  94.  
  95.         if(((undo->endline-undo->begline)==1) && (undo->endcol<STRING_LENGTH))
  96.         {  /* ein Ausschnitt aus einer Zeile */
  97.             undo->endcol=undo->begcol+end->used;
  98.         }
  99. /*
  100. printf("\33H*%ld %ld %d %d %d*",
  101.               undo->begline,
  102.               undo->endline,
  103.               undo->begcol,
  104.               undo->endcol,
  105.               end->used);
  106. form_alert(1,"[0][ ][OK]");
  107. */
  108.         undo->endcol=min(undo->endcol,STRING_LENGTH);
  109.         undo->blktype=wp->w_state&COLUMN;
  110.     }
  111. }
  112.  
  113. static void cut(WINDOW *wp)
  114. {
  115.     free_undoblk(wp,undo.blkbeg);
  116.     Wrestblk(wp, &undo, &undo.blkbeg, &undo.blkend);
  117. /*
  118. printf("\33H*%ld %ld %d %d %d %d*",
  119.               begline,endline,
  120.               undo.blkbeg->begcol,
  121.               undo.blkbeg->endcol,
  122.               undo.blkend->begcol,
  123.               undo.blkend->endcol);
  124. form_alert(1,"[0][ ][OK]");
  125. */
  126.     evnt_timer(125,0);
  127.     if(undo.blktype==COLUMN)
  128.         cut_col(wp,undo.blkbeg,undo.blkend);
  129.     else
  130.         cut_blk(wp,undo.blkbeg,undo.blkend);
  131.     Wcuron(wp);
  132.     undo.menu=WINEDIT;
  133.     undo.item=EDITPAST;
  134. }
  135.  
  136. static void paste(WINDOW *wp)
  137. {
  138.     LINESTRUCT *begcopy=NULL, *endcopy=NULL;
  139.     
  140.     if((undo.flag=copy_blk(wp,undo.blkbeg,undo.blkend,&begcopy,&endcopy))>0)
  141.     {
  142.         store_undo(wp, &undo, begcopy, endcopy, WINEDIT, EDITCUT);
  143. /*
  144. printf("\33H*%ld %ld %d %d %d %d*",
  145.               begline,endline,
  146.               undo.blkbeg->begcol,
  147.               undo.blkbeg->endcol,
  148.               undo.blkend->begcol,
  149.               undo.blkend->endcol);
  150. form_alert(1,"[0][ ][OK]");
  151. */
  152.         if(undo.blktype==COLUMN)
  153.             paste_col(wp,begcopy,endcopy);
  154.         else
  155.               paste_blk(wp,begcopy,endcopy);
  156.         undo.menu=WINEDIT;
  157.         undo.item=EDITCUT;
  158.     }
  159. }
  160.  
  161. static void line(WINDOW *wp)
  162. {
  163.     char *cp;
  164.     int savecol;
  165.  
  166.     strcpy(savestr,wp->cstr->string);
  167.     if(wp->cstr->len < (strlen(undo.string)+1))
  168.     {
  169.         if(cp=realloc(wp->cstr->string,(strlen(undo.string)+1)))
  170.         {
  171.             wp->cstr->string=cp;
  172.             wp->cstr->len=(strlen(undo.string)+1);
  173.         }
  174.         else
  175.         {
  176.             undo.item=FALSE;
  177.             return;
  178.         }
  179.     }
  180.     strcpy(wp->cstr->string,undo.string);
  181.     wp->cstr->used=strlen(undo.string);
  182.     savecol=wp->col;
  183.     wp->col=undo.col;                  /* Cursor setzen */
  184.     undo.col=savecol;
  185.     refresh(wp, wp->cstr, max(0,(min(wp->col,savecol)-1)), wp->row);
  186.     strcpy(undo.string,savestr);
  187.     undo.item=LINEUNDO;
  188. }
  189.  
  190. void do_undo(WINDOW *wp)                                         /* Undo ausführen */
  191. {
  192.     int msgbuf[8];
  193.     LINESTRUCT *dummy=NULL;
  194.     
  195.     extern LINESTRUCT *begcut, *endcut;
  196.     extern OBJECT *winmenu;
  197.             
  198.     if(wp)
  199.     {
  200.         if(undo.flag!=TRUE)
  201.         {
  202.             free_undoblk(wp, undo.blkbeg);
  203.             form_alert(1,Aundo[0]);
  204.             undo.item=FALSE;
  205.             return;
  206.         }
  207.         graf_mouse(M_OFF,0L);
  208.         Wcursor(wp);
  209.         switch(undo.item)
  210.         {
  211.             case EDITCUT:
  212.                 cut(wp);
  213.                 break;
  214.             case EDITPAST:
  215.                 paste(wp);
  216.                 break;
  217.             case LINEUNDO:
  218.                 line(wp);
  219.                 break;
  220.             case LINEPAST:
  221.                 line(wp);
  222.                 paste(wp);
  223.                 undo.item=CUTLINE;
  224.                 break;
  225.             case CUTLINE:
  226.                 cut(wp);
  227.                 line(wp);
  228.                 undo.item=LINEPAST;
  229.                 break;
  230.             case CUTPAST:
  231.                 Wrestblk(wp, &undo, &begcut, &endcut);
  232.                 evnt_timer(125,0);
  233.                 if(undo.blktype==COLUMN)
  234.                     cut_col(wp, begcut, endcut);
  235.                 else
  236.                     cut_blk(wp, begcut, endcut);
  237.                 free_blk(wp,begcut);
  238.                 Wcuron(wp);
  239.                 paste(wp);
  240.                 undo.item=FALSE;
  241.                 break;
  242.             case PASTCUT:
  243.                 break;
  244.             case WINCLOSE:
  245.                 msgbuf[0]=MN_SELECTED;
  246. #if GEMDOS
  247.                 msgbuf[1]=_GemParBlk.global[2];
  248. #else
  249.                 msgbuf[1]=gb.gb_pglobal[2];
  250. #endif
  251.                 msgbuf[2]=Wh(wp);
  252.                 msgbuf[3]=undo.menu;
  253.                 msgbuf[4]=undo.item;
  254.                 menu_tnormal(winmenu,msgbuf[3],0);
  255.                 appl_write(msgbuf[1],16,msgbuf);
  256.                 break;    
  257.         }
  258.         wp->cspos=wp->col;
  259.         Wcursor(wp);
  260.         graf_mouse(M_ON,0L);
  261.         switch(undo.item)
  262.         {
  263.             case BACKSPACE:
  264.                 editor(wp,0,BACKSPACE,&dummy,&dummy);
  265.                 undo.item=RETURN;
  266.                 break;
  267.             case RETURN:
  268.                 editor(wp,0,RETURN,&dummy,&dummy);
  269.                 undo.item=BACKSPACE;
  270.                 break;
  271.         }
  272.     }
  273. }
  274.